/* SPDX-License-Identifier: GPL-2.0 */

#ifndef __DIM_BASELINE_H
#define __DIM_BASELINE_H

#include "../common/dim_hash.h"
#include "../common/dim_rb_tree.h"
#include "dim_core_policy.h"

/**
 * typedef dim_malloc - memory alloc function
 * @size: alloc size on byte
 *
 * Return: pointer to allocated memory block on success or NULL on failure
 */
typedef void* (*dim_malloc)(unsigned long size);

/**
 * typedef dim_free - memory free function
 * @data: memery block to be freed
 */
typedef void (*dim_free)(void *data);

/**
 * enum dim_baseline_type - flag of baseline type
 */
enum dim_baseline_type {
	DIM_BASELINE_USER,
	DIM_BASELINE_KERNEL,
	DIM_BASELINE_TRAMPOLINE,
	DIM_BASELINE_LAST,
};

/**
 * struct dim_baseline_node - single baseline data
 * @filename: filename of baseline data
 * @algo: hash algorithm
 * @type: baseline type
 * @action: tampered action
 * @data: main hash data
 */
struct dim_baseline_node {
	char *filename;
	enum dim_hash_type algo;
	enum dim_baseline_type type;
	enum dim_core_policy_action action;
	unsigned char *data;
};

/**
 * struct dim_baseline_handle - handle of baseline dataset
 * @list: rb tree for data management
 * @malloc_func: memory alloc function
 * @free_func: memory free function
 */
struct dim_baseline_handle {
	dim_rb_handle list;
	dim_malloc malloc_func;
	dim_free free_func;
};

/* API for baseline node */

/**
 * dim_baseline_node_create - create and init a baseline node
 * @handle: baseline handle
 *
 * Return: pointer to the created node or errno on failure (via ERR_PTR)
 */
struct dim_baseline_node *
dim_baseline_node_create(struct dim_baseline_handle *handle);

/**
 * dim_baseline_node_destroy - destroy a baseline node
 * @handle: baseline handle
 * @node: baseline node to be freed
 */
void dim_baseline_node_destroy(struct dim_baseline_handle *handle,
			       struct dim_baseline_node *node);

/**
 * dim_baseline_node_set_filename - set filename of a baseline node
 * @handle: baseline handle
 * @node: baseline node to be operated
 * @filename: pointer to filename string
 *
 * Return: 0 on success or errno on failure
 */
int dim_baseline_node_set_filename(struct dim_baseline_handle *handle,
				   struct dim_baseline_node *node,
				   const char *filename);

/**
 * dim_baseline_node_set_type - set type of a baseline node
 * @handle: baseline handle
 * @node: baseline node to be operated
 * @type: baseline type flag
 *
 * Return: 0 on success or -errno on failure
 */
int dim_baseline_node_set_type(struct dim_baseline_handle *handle,
			       struct dim_baseline_node *node,
			       enum dim_baseline_type type);

/**
 * dim_baseline_node_set_action - set action of a baseline node
 * @handle: baseline handle
 * @node: baseline node to be operated
 * @action: baseline action flag
 *
 * Return: 0 on success or -errno on failure
 */
int dim_baseline_node_set_action(struct dim_baseline_handle *handle,
				struct dim_baseline_node *node,
				enum dim_core_policy_action action);

/**
 * dim_baseline_node_set_type_str - set type of a baseline node by string
 * @handle: baseline handle
 * @node: baseline node to be operated
 * @str: string of baseline type
 *
 * Return: 0 on success or errno on failure
 */
int dim_baseline_node_set_type_str(struct dim_baseline_handle *handle,
				   struct dim_baseline_node *node,
				   const char *str);

/**
 * dim_baseline_node_set_hash_algo - set hash algorithm of a baseline node
 * @handle: baseline handle
 * @node: baseline node to be operated
 * @type: hash algorithm flag
 *
 * Return: 0 on success or errno on failure
 */
int dim_baseline_node_set_hash_algo(struct dim_baseline_handle *handle,
				    struct dim_baseline_node *node,
				    enum dim_hash_type type);

/**
 * dim_baseline_node_set_hash_algo_str - set hash algorithm of a baseline
 * node by string
 * @handle: baseline handle
 * @node: baseline node to be operated
 * @str: string of hash algorithm flag
 *
 * Return: 0 on success or errno on failure
 */
int dim_baseline_node_set_hash_algo_str(struct dim_baseline_handle *handle,
					struct dim_baseline_node *node,
					const char *str);

/**
 * dim_baseline_node_set_main_hash_data - set main hash data of baseline node
 * @handle: baseline handle
 * @node: baseline node to be operated
 * @data: pointer to the hash data array to set
 * @data_len: length of hash data
 *
 * Return: 0 on success or errno on failure
 */
int dim_baseline_node_set_main_hash_data(struct dim_baseline_handle *handle,
					 struct dim_baseline_node *node,
					 unsigned char *data,
					 unsigned int data_len);

/**
 * dim_baseline_node_set_main_hash_data_str - set main hash data of a baseline
 * node by string
 * @handle: baseline handle
 * @node: baseline node to be operated
 * @str: string of hash data
 *
 * Return: 0 on success or errno on failure
 */
int dim_baseline_node_set_main_hash_data_str(struct dim_baseline_handle *handle,
					     struct dim_baseline_node *node,
					     const char *str);

/**
 * dim_baseline_node_compare - copmare two baseline node data
 * @node1: baseline node
 * @node2: baseline node
 *
 * Return: 0 or 1 or -1
 */
int dim_baseline_node_compare(struct dim_baseline_node *node1,
			      struct dim_baseline_node *node2);

/* API for baseline handle */

/**
 * dim_create_baseline - create and init a baseline handle
 * @comp: compare function of rb tree
 * @malloc: memory alloc function
 * @free: memory free function
 *
 * Return: 0 on success or errno on failure
 */
struct dim_baseline_handle *dim_baseline_handle_create(dim_rb_compare comp,
						       dim_malloc malloc,
						       dim_free free);

/**
 * dim_baseline_handle_destroy - destroy a baseline handle
 * @handle: baseline handle to destroy
 */
void dim_baseline_handle_destroy(struct dim_baseline_handle *handle);

/**
 * dim_baseline_add_node - add a baseline data node
 * @handle: baseline handle
 * @node: baseline data node to be added
 *
 * Return: 0 on success or errno on failure
 */
int dim_baseline_add_node(struct dim_baseline_handle *handle,
			  struct dim_baseline_node *node);


/**
 * dim_baseline_search_node - search and returns baseline data node
 * @handle: baseline handle
 * @node: baseline data node with search criterion (based on compare function)
 *
 * Return: pointer to node on success or NULL on failure
 */
struct dim_baseline_node *
dim_baseline_search_node(struct dim_baseline_handle *handle,
			 struct dim_baseline_node *node);

#endif
